package com.beemans.common.ui.adapter

import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2

/**
 * @author tiamosu
 * @date 2021/6/21.
 */
class CustomFragmentStateAdapter(
    fragment: Fragment,
    private val viewPager2: ViewPager2,
    private var fragments: List<Fragment>,
    private val maxOffscreenPageLimit: Int? = null,
    private val callback: Callback? = null,
) : FragmentStateAdapter(fragment) {
    private val createdIds = arrayListOf<Long>()
    private val ids = arrayListOf<Long>()

    init {
        viewPager2.adapter = this
        updateDataSetChanged(fragments)
    }

    fun updateDataSetChanged(fragments: List<Fragment>) {
        if (fragments.isNullOrEmpty()) {
            return
        }

        this.fragments = fragments
        var offscreenPageLimit = fragments.size
        if (maxOffscreenPageLimit != null) {
            offscreenPageLimit = offscreenPageLimit.coerceAtMost(maxOffscreenPageLimit)
        }
        viewPager2.offscreenPageLimit = offscreenPageLimit

        if (ids.isNotEmpty()) {
            ids.clear()
        }
        fragments.forEach {
            ids.add(it.hashCode().toLong())
        }

        notifyDataSetChanged()
    }

    override fun getItemCount() = fragments.size

    override fun createFragment(position: Int): Fragment {
        ids.getOrNull(position)?.let {
            if (!createdIds.contains(it)) {
                createdIds.add(it)
            }
        }
        return (fragments.getOrNull(position) ?: Fragment()).apply {
            callback?.onCallback(this, position)
        }
    }

    override fun getItemId(position: Int): Long {
        return ids.getOrNull(position) ?: RecyclerView.NO_ID
    }

    override fun containsItem(itemId: Long) = createdIds.contains(itemId)

    fun interface Callback {
        fun onCallback(fragment: Fragment, position: Int)
    }
}